<?php

namespace Easy;

use Easy\Entity\Hook;
use Easy\Entity\IDGenter;

class Entity
{

    public static function getByCond(array $cond)
    {
        $cls            = get_called_class();
        $cls            = new $cls;
        $tableName      = $cls->getTable();
        $dbInstanceName = $cls->getDbInstance();
        $dbInstance     = DbContainer::get($dbInstanceName);
        $row            = $dbInstance->table($tableName)->where($cond)->fetchRow();
        if (!$row) {
            return null;
        }
        $cls->id = $row['id'];
        Hook::setModel($cls, Hook::SQL_FETCH);
        foreach ($row as $k => $v) {
            $cls->$k = $v;
        }
        Hook::cleanModel($cls);

        return $cls;
    }

    public static function getByIndex($index, $indexVal)
    {
        return self::getByCond([$index => $indexVal]);
    }

    public static function getByID($id)
    {
        return self::getByCond(['id' => $id]);
    }

    public static function listByDTO(DTO $clsDTO)
    {
        $clsName        = get_called_class();
        $cls            = new $clsName;
        $tableName      = $cls->getTable();
        $dbInstanceName = $cls->getDbInstance();
        $dbInstance     = DbContainer::get($dbInstanceName);
        $lists          = $dbInstance->table($tableName)->where($clsDTO->toArr(DTO::FILTER_EMPTY))->fetchAll();
        if (!$lists) {
            return null;
        }
        $newLists = [];
        foreach ($lists as $row) {
            $tmpCls     = new $clsName;
            $tmpCls->id = $row['id'];
            Hook::setModel($tmpCls, Hook::SQL_FETCH);
            foreach ($row as $k => $v) {
                $tmpCls->$k = $v;
            }
            Hook::cleanModel($tmpCls);
            $newLists[] = $tmpCls;
        }

        return $newLists;
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowAttr())) {
            $this->$name = $value;
        } else {
            Hook::clsSet($this, $name, $value);
        }
    }

    public function __get($name)
    {
        if (in_array($name, $this->allowAttr())) {
            return $this->$name;
        } else {
            return Hook::clsGet($this, $name);
        }
    }

    protected static function create($cls)
    {
        $cls = new $cls;
        $cls->setID();
        $cls->setCreatetime();
        Hook::setModel($cls, Hook::SQL_INSERT);

        return $cls;
    }

    protected function setID($id = null)
    {
        $this->id = $id ? $id : IDGenter::getLastID($this->getDbInstance());
    }

    public function getID()
    {
        return $this->id;
    }
    
    public function delete()
    {
        Hook::setModel($this, Hook::SQL_DELETE);
    }

    protected function setCreatetime()
    {
        $this->created = date('Y-m-d H:i:s');
    }

    protected function getCreatetime()
    {
        return $this->created;
    }

    protected function allowAttr()
    {
        return ['id', 'created'];
    }

    public function getTable()
    {
        $cls = get_called_class();

        return str_replace('\\', '_', $cls);
    }

    public function toDTO(DTO $dto)
    {
        foreach ($dto as $k => $v) {
            $dto->$k = $this->$k;
        }

        return $dto;
    }

    public function getDbInstance()
    {
        return '';
    }

    public function getObjVars()
    {
        return get_object_vars($this);
    }
}